/*

    This file is part of Hometree.

    Hometree is free software: you can redistribute it and/or modify
    it under the terms of the GNU Lesser General Public License as published by
    the Free Software Foundation, either version 3 of the License, or
    (at your option) any later version.

    Hometree is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU Lesser General Public License for more details.

    You should have received a copy of the GNU Lesser General Public License
    along with Hometree.  If not, see <http://www.gnu.org/licenses/>.

    Copyright 2011,2012 Roman Held

*/
#ifndef _HTR_MANAGED_SOCKET_HEADER_
#define _HTR_MANAGED_SOCKET_HEADER_

#include <QTcpSocket>
#include <QDataStream>
#include <QByteArray>

class HtrManagedSocket: public QObject
{
  Q_OBJECT
  public:
    HtrManagedSocket(QObject *parent = NULL);
    HtrManagedSocket(QTcpSocket *socket, QObject *parent = NULL);
    virtual ~HtrManagedSocket();


    // Socket-Management
    bool          connectToHost(const QString &hostName, quint16 port, int timeout);
    void          connectToHost(const QString &hostName, quint16 port);
    void          disconnectFromHost();
    void          setSocket(QTcpSocket *socket);
    QTcpSocket   *socket() const;
    QAbstractSocket::SocketState   state() const;
    bool          isConnected() const;
    void          close();
    bool          flush();
    QString       ident() const;
      
    // Reading 
    QDataStream&       readStream();
    const QByteArray&  readByteArray() const;
    bool               next();
    int                paketsAvailable() const;

    // Writing
    QDataStream &prepareStream();   // verwendet einen internen Buffer
    bool         writeStream();
    bool         writeByteArray(const QByteArray &buffer);
    static void  setupStream(QDataStream &stream);  // setzt die intern verwendete Qt-Version

  signals:
    void reading();    // empfaengt Daten
    void readyRead();  // bereit fuer naechsten "readData()"
    void writing();    // sendet Daten
    void error(QAbstractSocket::SocketError socketError);
    void stateChanged(QAbstractSocket::SocketState socketState);
    void hasConnected(bool);

  private slots:
    void processData();
    void processState(QAbstractSocket::SocketState socketState);

  private:
    void destroy();
    void setup();

    QTcpSocket        *mSocket;
    QList<QByteArray>  mPakets;        // vollstaendig empfangene Pakete

    // Daten auslesen (while (next()) ....)
    QByteArray         mReadingPaket;
    QDataStream       *mReadingStream;
 
    // Daten senden
    QByteArray         mWritingPaket; 
    QDataStream       *mWritingStream;
    
    // Datenempfang 
    QByteArray         mFrame;         // angefangenes Paket (processData())
    qint32             mFrameSize;     // 4GB muessen reichen... wir verzichten auf qint64..
};

#endif
